package com.qcrud.mapper;

import com.qcrud.Qcrud;
import com.qcrud.annotations.*;
import com.qcrud.core.SqlCommandType;
import com.qcrud.core.SqlManager;
import com.qcrud.core.SqlMetaData;
import com.qcrud.exception.QcrudException;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Slf4j
public record MapperMethod(Qcrud qcrud, Method method) {

    public Object execute(Object[] args) {
        String methodName = method.getName();
        log.debug("execute mapper method: " + methodName);
        String key = method.getDeclaringClass().getName() + "." + methodName;
        SqlMetaData sqlMetaData = SqlManager.get(key);
        if (null == sqlMetaData) {
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                if (annotation instanceof SqlInsert) {
                    SqlInsert sqlInsert = (SqlInsert) annotation;
                    sqlMetaData = new SqlMetaData(SqlCommandType.insert, sqlInsert.value());
                } else if (annotation instanceof SqlDelete) {
                    SqlDelete sqlDelete = (SqlDelete) annotation;
                    sqlMetaData = new SqlMetaData(SqlCommandType.delete, sqlDelete.value());
                } else if (annotation instanceof SqlUpdate) {
                    SqlUpdate sqlUpdate = (SqlUpdate) annotation;
                    sqlMetaData = new SqlMetaData(SqlCommandType.update, sqlUpdate.value());
                } else if (annotation instanceof SqlSelect) {
                    SqlSelect sqlSelect = (SqlSelect) annotation;
                    sqlMetaData = new SqlMetaData(SqlCommandType.select, sqlSelect.value());
                } else if (annotation instanceof SqlCall) {
                    SqlCall sqlCall = (SqlCall) annotation;
                    sqlMetaData = new SqlMetaData(SqlCommandType.select, sqlCall.value());
                }
            }
            if (null == sqlMetaData) {
                throw new QcrudException("Cannot execute method: " + key);
            }
            SqlManager.put(key, sqlMetaData);
        }
        return qcrud.execute(sqlMetaData, args);
    }
}

